<?php

if (!function_exists('ip')) {

    /**
     * @desc 獲取客户端真實IP地址，如果項目有反向代理需要設置信任ip,
     *       request()->setTrustedProxies('192.168.100.1/24')
     * @return mixed
     */
    function ip()
    {
        static $ip = null;
        if (is_null($ip)) {
            $ip = request()->getClientIp();
        }

        return $ip;
    }
}

/**
 * 將數組中null轉成''
 */
if (!function_exists('null2char')) {
    function null2char($input)
    {
        return array_map(function ($value) {
            return is_null($value) ? '' : $value;
        }, $input);
    }
}

/**
 * 判斷search數組是否在haystack中
 * @param $search   搜索數組
 * @param $haystack 大數組集合
 * @return bool
 */
if (!function_exists('arr_in_array')) {
    function arr_in_array(array $search, array $haystack)
    {
        $search   = $search ?? [];
        $haystack = $haystack ?? [];
        $compare  = array_map(function ($item) use ($haystack) {
            if (!in_array($item, $haystack)) {
                return 'not';
            }
            return 'pass';
        }, $search);
        if (in_array('not', $compare)) {
            return false;
        }
        return true;
    }
}

/**
 * 判斷給的多個數組是否都是空值,包含子元素全為空
 * @return bool
 */
if (!function_exists('array_empty')) {
    function array_empty(...$arrs)
    {
        $ret = array_map(function ($arr) {
            $arr = array_filter((array)$arr);
            if (!empty($arr) && count($arr) > 0) {
                return 'not';
            }
            return 'pass';
        }, $arrs);
        if (in_array('not', $ret)) {
            return false;
        }
        return true;
    }
}

/**
 * 對用户的id進行隱碼
 */
if (!function_exists('umaskId')) {
    /**
     * 最後last個數字轉成mask個*號
     * @param     $id
     * @param int $mask
     * @param int $last
     * @return string
     */
    function umaskId($id, $mask = 4, $last = 2)
    {
        $mask = str_repeat('*', $mask);
        if ($last >= strlen($id)) {
            return $mask;
        }
        return preg_replace("/(\d+)?(\d{" . $last . "})/", "\${1}" . $mask, $id);
    }
}

if (!function_exists('collectToTree')) {
    /**
     * laravel collection 轉樹結構數組，根節點的id須為0
     * @param \Illuminate\Support\Collection $collect
     * @param  array                         $options [root,id,parent_id,sort,children]
     * @return array
     */
    function collectToTree(\Illuminate\Support\Collection $collect,
                           array $options = ['first' => 1])
    {
        $branch = [];

        if ($options['first']) {
            $options = array_merge(
                [
                    'root'      => 0,
                    'id'        => 'id',
                    'parent_id' => 'parent_id',
                    'sort'      => 'sort',
                    'children'  => 'childrens',
                ],
                $options);
            $collect = $collect->sortBy($options['sort']);
        }

        $collect->map(function ($m) use ($collect, &$branch, $options) {
            if ($m->{$options['parent_id']} == $options['root']) {
                $children = collectToTree($collect, array_merge($options,
                    [
                        'root'  => $m->{$options['id']},
                        'first' => 0,
                    ]
                ));
                if ($children) {
                    $m->{$options['children']} = $children;
                }
                $branch[] = $m->toArray();
            }
        });

        return $branch;
    }
}

if (!function_exists('broute')) {
    function broute($name, $parameters = null, $absolute = false)
    {
        $char    = '__';
        $pattern = '/^\{\{([^\{\}]+)\}\}$/';
        if (is_scalar($parameters)) {
            if (!preg_match($pattern, $parameters)) {
                return route($name, $parameters, $absolute);
            }
            $parameters = [$parameters];
        }
        $params   = [];
        $mappings = [];
        collect($parameters)->each(function ($item, $key) use (&$params, &$mappings, $char, $pattern) {
            if (preg_match($pattern, $key, $matches)) {
                $original_key   = $key;
                $key            = $char . $matches[1] . $char;
                $mappings[$key] = $original_key;
            }
            if (is_scalar($item) && preg_match($pattern, $item, $matches)) {
                $original_item   = $item;
                $item            = $char . $matches[1] . $char;
                $mappings[$item] = $original_item;
            }
            $params[$key] = trim($item);
        });
        $url = route($name, $params, $absolute);
        return strtr($url, $mappings);
    }
}

if (!function_exists('parseRedisClustersEnvironment')) {
    function parseRedisClustersEnvironment($environment = '')
    {
        // redis 集羣配置
        $environments = explode(',', $environment);
        $clusters     = [];

        foreach ($environments as $database => $cluster) {
            [$host, $port] = explode(':', $cluster, 2);
            $clusters[] = [
                'host'     => $host,
                'port'     => $port ?? 6379,
                'database' => $database,
            ];
        }

        return $clusters;
    }
}

if (!function_exists('route_class')) {
    /**
     * 根据当前路由 生成 class
     * @return mixed
     */
    function route_class()
    {
        return str_replace('.', '-', Route::currentRouteName());
    }
}

if (!function_exists('assert_images')) {
    /**
     * 七牛 images 镜像空间
     * @param      $path
     * @param null $test
     * @return mixed
     */
    function assert_images($path, $test = null)
    {
        if (substr($path, 0, 1) != '/') {
            $path = '/' . $path;
        }
        if ($test) {
            return env('APP_IMAGES_URL') . $path;
        }
        return config('app.urls.images') . $path;
    }
}

if (!function_exists('assert_cdns')) {
    /**
     * 七牛 cdns 镜像空间
     * @param      $path
     * @param null $secure
     * @return mixed
     */
    function assert_cdns($path, $secure = null)
    {
        if (substr($path, 0, 1) != '/') {
            $path = '/' . $path;
        }
        return config('app.urls.assert') . $path;
    }
}

if (!function_exists('default_img')) {
    function default_img($img = null)
    {
        if (empty($img)) {
            return "";
        } else {
            return assert_images($img);
        }
    }
}

if (!function_exists('make_excerpt')) {
    function make_excerpt($value, $length = 200)
    {
        $excerpt = trim(preg_replace('/\r\n|\r|\n+/', ' ', strip_tags($value)));
        return str_limit($excerpt, $length);
    }
}

if (!function_exists('markdownToHtml')) {
    /**
     * markdown 转 html
     * @param string $markdown markdown文本
     * @param string $rule     markdownNoH1_6 markdown 规则
     * @param null   $limit    限制大小
     * @return mixed
     */
    function markdownToHtml($markdown, $rule = 'markdownNoH1_6', $limit = null)
    {
        // 截取大小
        if ($limit) {
            if (is_numeric($limit)) {
                $markdown = substr($markdown, 0, $limit);
            } else {
                $markdown = substr($markdown, 0, strlen($markdown) / 3);
            }
        }

        // markdown to html
        $convertedHmtl = app('Parsedown')->setBreaksEnabled(true)->text($markdown);

        /** XSS 防注入 */
        $convertedHmtl = clean($convertedHmtl, $rule);

        // 代码高亮展示优化
        $convertedHmtl = str_replace("<pre><code>", '<pre><code class=" language-php">', $convertedHmtl);

        // 移除 {{}}
        // $convertedHmtl = remove_vue($convertedHmtl);

        // 返回 html
        return $convertedHmtl;
    }
}
